<template>
  <div class="simple-vis-network">
    <!-- 网络图画布 -->
    <div ref="networkContainer" class="network-canvas"></div>

    <!-- 编辑工具栏 -->
    <div v-if="selectedElement" class="edit-toolbar">
      <el-card class="toolbar-card">
        <template #header>
          <div class="toolbar-header">
            <span>编辑元素</span>
            <el-button type="danger" text @click="clearSelection">
              <el-icon>
                <Close />
              </el-icon>
            </el-button>
          </div>
        </template>

        <!-- 节点编辑 -->
        <div v-if="selectedElement.type === 'node'" class="edit-form">
          <el-form label-width="80px">
            <el-form-item label="节点标签">
              <el-input v-model="selectedElement.data.label" @change="updateSelectedElement" />
            </el-form-item>
            <el-form-item label="节点类型">
              <el-select v-model="selectedElement.data.group" @change="updateSelectedElement">
                <el-option label="用户" value="user" />
                <el-option label="产品" value="product" />
                <el-option label="订单" value="order" />
                <el-option label="分类" value="category" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="danger" @click="deleteSelectedElement">
                <el-icon>
                  <Delete />
                </el-icon>
                删除节点
              </el-button>
            </el-form-item>
          </el-form>
        </div>

        <!-- 边编辑 -->
        <div v-else class="edit-form">
          <el-form label-width="80px">
            <el-form-item label="关系标签">
              <el-input v-model="selectedElement.data.label" @change="updateSelectedElement" />
            </el-form-item>
            <el-form-item>
              <el-button type="danger" @click="deleteSelectedElement">
                <el-icon>
                  <Delete />
                </el-icon>
                删除关系
              </el-button>
            </el-form-item>
          </el-form>
        </div>
      </el-card>
    </div>

    <!-- 添加节点按钮 -->
    <div class="add-node-toolbar">
      <el-button type="primary" @click="showAddNodeDialog = true">
        <el-icon>
          <Plus />
        </el-icon>
        添加节点
      </el-button>

      <el-button type="success" :disabled="!selectedNodes.length" @click="startAddEdge">
        <el-icon>
          <Connection />
        </el-icon>
        添加关系
      </el-button>
    </div>

    <!-- 添加节点对话框 -->
    <el-dialog v-model="showAddNodeDialog" title="添加新节点" width="400px">
      <el-form :model="newNode" label-width="80px">
        <el-form-item label="节点标签">
          <el-input v-model="newNode.label" />
        </el-form-item>
        <el-form-item label="节点类型">
          <el-select v-model="newNode.group">
            <el-option label="用户" value="user" />
            <el-option label="产品" value="product" />
            <el-option label="订单" value="order" />
            <el-option label="分类" value="category" />
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="showAddNodeDialog = false">取消</el-button>
        <el-button type="primary" @click="addNewNode">确认添加</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { DataSet } from 'vis-data'
import { Network } from 'vis-network'
import { Close, Delete, Plus, Connection } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

// Refs
const networkContainer = ref(null)
const selectedElement = ref(null)
const selectedNodes = ref([])
const showAddNodeDialog = ref(false)
const isAddingEdge = ref(false)

// 新节点数据
const newNode = ref({
  label: '',
  group: 'user'
})

// 网络实例和数据
let network = null
let nodes = null
let edges = null

// 生成模拟数据
const generateMockData = () => {
  // 节点数据
  const mockNodes = new DataSet([
    {
      id: 1,
      label: '用户A',
      group: 'user',
      color: '#4CAF50'
    },
    {
      id: 2,
      label: '产品X',
      group: 'product',
      color: '#2196F3'
    },
    {
      id: 3,
      label: '订单001',
      group: 'order',
      color: '#FF9800'
    },
    {
      id: 4,
      label: '分类Tech',
      group: 'category',
      color: '#9C27B0'
    }
  ])

  // 边数据
  const mockEdges = new DataSet([
    {
      id: 1,
      from: 1,
      to: 2,
      label: '购买',
      arrows: 'to',
      color: '#4CAF50'
    },
    {
      id: 2,
      from: 1,
      to: 3,
      label: '创建',
      arrows: 'to',
      color: '#2196F3'
    },
    {
      id: 3,
      from: 2,
      to: 4,
      label: '属于',
      arrows: 'to',
      color: '#9C27B0'
    }
  ])

  return { nodes: mockNodes, edges: mockEdges }
}

// 网络配置
const getNetworkOptions = () => {
  return {
    physics: {
      enabled: true,
      stabilization: { iterations: 100 }
    },
    interaction: {
      hover: true,
      selectable: true,
      multiselect: true
    },
    nodes: {
      shape: 'dot',
      size: 25,
      font: {
        size: 14,
        face: 'Tahoma'
      },
      borderWidth: 2
    },
    edges: {
      width: 2,
      font: {
        size: 12,
        align: 'middle'
      },
      smooth: true,
      arrows: {
        to: { enabled: true, scaleFactor: 1 }
      }
    },
    groups: {
      user: {
        color: { background: '#4CAF50', border: '#388E3C' },
        font: { color: 'white' }
      },
      product: {
        color: { background: '#2196F3', border: '#1976D2' },
        font: { color: 'white' }
      },
      order: {
        color: { background: '#FF9800', border: '#F57C00' },
        font: { color: 'white' }
      },
      category: {
        color: { background: '#9C27B0', border: '#7B1FA2' },
        font: { color: 'white' }
      }
    }
  }
}

// 初始化网络
const initializeNetwork = () => {
  if (!networkContainer.value) return

  const data = generateMockData()
  nodes = data.nodes
  edges = data.edges

  const options = getNetworkOptions()

  network = new Network(networkContainer.value, { nodes, edges }, options)

  // 绑定事件
  network.on('click', handleClick)
  network.on('select', handleSelect)
  network.on('deselectNode', handleDeselect)
}

// 点击事件处理
const handleClick = (params) => {
  if (params.nodes.length > 0) {
    const nodeId = params.nodes[0]
    const node = nodes.get(nodeId)
    selectedElement.value = {
      type: 'node',
      data: node
    }
  } else if (params.edges.length > 0) {
    const edgeId = params.edges[0]
    const edge = edges.get(edgeId)
    selectedElement.value = {
      type: 'edge',
      data: edge
    }
  } else {
    selectedElement.value = null
  }
}

// 选择事件处理
const handleSelect = (params) => {
  selectedNodes.value = params.nodes

  if (isAddingEdge.value && selectedNodes.value.length === 2) {
    createNewEdge()
  }
}

// 取消选择
const handleDeselect = () => {
  selectedNodes.value = []
  isAddingEdge.value = false
}

// 更新选中的元素
const updateSelectedElement = () => {
  if (selectedElement.value.type === 'node') {
    nodes.update(selectedElement.value.data)
  } else {
    edges.update(selectedElement.value.data)
  }
  ElMessage.success('更新成功')
}

// 删除选中的元素
const deleteSelectedElement = () => {
  if (selectedElement.value.type === 'node') {
    // 删除节点前先删除相关的边
    const connectedEdges = edges.get({
      filter: (edge) => edge.from === selectedElement.value.data.id || edge.to === selectedElement.value.data.id
    })

    edges.remove(connectedEdges.map(edge => edge.id))
    nodes.remove(selectedElement.value.data.id)
    ElMessage.success('节点已删除')
  } else {
    edges.remove(selectedElement.value.data.id)
    ElMessage.success('关系已删除')
  }

  selectedElement.value = null
}

// 清空选择
const clearSelection = () => {
  selectedElement.value = null
  if (network) {
    network.unselectAll()
  }
}

// 添加新节点
const addNewNode = () => {
  if (!newNode.value.label) {
    ElMessage.warning('请输入节点标签')
    return
  }

  const nodeId = Math.max(...nodes.getIds()) + 1
  const nodeColor = getColorByGroup(newNode.value.group)

  nodes.add({
    id: nodeId,
    label: newNode.value.label,
    group: newNode.value.group,
    color: nodeColor
  })

  showAddNodeDialog.value = false
  newNode.value = { label: '', group: 'user' }
  ElMessage.success('节点添加成功')
}

// 开始添加关系
const startAddEdge = () => {
  if (selectedNodes.value.length !== 2) {
    ElMessage.warning('请选择两个节点来创建关系')
    return
  }

  isAddingEdge.value = true
  ElMessage.info('请选择第二个节点来创建关系')
}

// 创建新关系
const createNewEdge = () => {
  const [from, to] = selectedNodes.value
  const edgeId = Math.max(...edges.getIds(), 0) + 1

  edges.add({
    id: edgeId,
    from: from,
    to: to,
    label: '新关系',
    arrows: 'to',
    color: '#666666'
  })

  isAddingEdge.value = false
  selectedNodes.value = []
  if (network) {
    network.unselectAll()
  }
  ElMessage.success('关系创建成功')
}

// 根据分组获取颜色
const getColorByGroup = (group) => {
  const colorMap = {
    user: '#4CAF50',
    product: '#2196F3',
    order: '#FF9800',
    category: '#9C27B0'
  }
  return colorMap[group] || '#666666'
}

// 生命周期
onMounted(() => {
  initializeNetwork()
})

onUnmounted(() => {
  if (network) {
    network.destroy()
  }
})
</script>

<style scoped>
.simple-vis-network {
  width: 100%;
  height: 600px;
  position: relative;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  background: white;
}

.network-canvas {
  width: 100%;
  height: 100%;
}

.edit-toolbar {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 300px;
  z-index: 10;
}

.toolbar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.edit-form {
  padding: 8px 0;
}

.add-node-toolbar {
  position: absolute;
  bottom: 16px;
  left: 16px;
  z-index: 10;
  display: flex;
  gap: 8px;
}

.toolbar-card {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
</style>